package com.xbongbong.saas.analytical.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.enums.OtherExpenseSheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.analytical.SaasValidateAnalyticalService;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.domain.entity.OtherExpenseEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaasOtherExpenseHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.model.OtherExpenseModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/07/15 16:04
 */
@Service("otherExpenseAnalyticalServiceImpl")
public class OtherExpenseValidateAnalyticalServiceImpl implements SaasValidateAnalyticalService {

    @Resource
    private OtherExpenseModel otherExpenseModel;
    @Resource
    private SaasOtherExpenseHelp saasOtherExpenseHelp;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.OTHER_EXPENSE.getCode(),XbbRefTypeEnum.RED_OTHER_EXPENSE.getCode());
    }

    @Override
    public void analyticalData(ValidateDataDTO validateDataDTO) throws XbbException {
        beforeSave(validateDataDTO);
    }
    
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        String corpid = validateDataDTO.getCorpid();
        JSONObject data = validateDataDTO.getData();
        //如果data内不存在类型，则把类型置入data内（注：审批内2种类型其他支出单的businessType都是统一为5710，所以要用data内的type来判断具体businessType。所以置入类型时需要判断data内是否已经存在类型，已经存在无需重置，且后续金额、时间校验要使用最正确的类型）
        OtherExpenseSheetTypeEnum otherSheetTypeEnum = OtherExpenseSheetTypeEnum.getByBusinessType(validateDataDTO.getBusinessType());
        //处理type
        String type = FastJsonHelper.getStringFromFormData(data, OtherExpenseEnum.SHEET_TYPE_OTHER.getAttr());
        if (StringUtil.isEmpty(type)){
            data.put(OtherExpenseEnum.SHEET_TYPE_OTHER.getAttr(), otherSheetTypeEnum.getCode());
        } else {
            otherSheetTypeEnum = OtherExpenseSheetTypeEnum.getByCode(type);
        }
        SheetTypeEnum sheetTypeEnum = otherSheetTypeEnum.getSheetTypeEnum();
        //校验金额，日期等
        SaveFormatHelp.otherBeforeSave(validateDataDTO, data, sheetTypeEnum);
        //处理关联原始支出单
        SaveFormatHelp.formatLinkBusiness4Save(data, OtherExpenseEnum.ORIGIN_ID.getAttr(), OtherExpenseEnum.ORIGIN_ID_LINK_TEXT.getAttr(), OtherExpenseEnum.ORIGIN_ID.getFieldType());
        if (Objects.equals(type, OtherExpenseSheetTypeEnum.RED_OTHER_EXPENSE.getCode())) {
            //先校验原单可红冲金额是否足够
            Long linkPreId = FastJsonHelper.getLongFromFormData(data, OtherExpenseEnum.ORIGIN_ID.getAttr());
            //关联原始支出单
            OtherExpenseEntity originEntity = otherExpenseModel.getByKey(linkPreId, corpid);
            if (Objects.isNull(originEntity)) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208045, PaymentErrorCodeEnum.API_ERROR_208045.getMsg(), OtherExpenseEnum.ORIGIN_ID.getAttrName());
            }
            JSONObject originData = JsonHelperUtil.getJSONObject(originEntity.getData());
            double originAmout = originData.getDoubleValue(OtherExpenseEnum.AMOUNT.getAttr());
            //原单已红冲金额
            double redAmount = saasOtherExpenseHelp.sumRedAmountBySheet(corpid, linkPreId);
            //剩余总的可红冲金额 = 关联原支出单总金额 - 原单总的已红冲金额(由于红冲金额为负数，因此此处用add)
            Double leftAmount = Arith.add(originAmout, redAmount);
            //其他支出单金额（此时还未处理成负数）
            Double sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(data, OtherExpenseEnum.AMOUNT.getAttr(), 0D);
            if (sheetAmount > leftAmount) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.DETAIL_BEYOND_AMOUNT_RED, OtherExpenseEnum.ORIGIN_ID.getAttrName());
            }
        }
        for (Map.Entry<String,Object> entry : SaasDataInitHelp.initPaymentSheet().entrySet()){
            SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        }

    }

}
